package com.example.demo.generator.controller;

import com.baomidou.mybatisplus.extension.api.R;
import com.example.demo.generator.entiy.TAddress;
import com.example.demo.generator.entiy.TCurrency;
import com.example.demo.generator.service.TAddressService;
import com.example.demo.generator.service.TCurrencyService;
import com.google.common.collect.ImmutableList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.crypto.*;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.wallet.DeterministicSeed;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RestController
@Api(tags="BTC钱包接口")
public class BTCController {

    @Autowired
    private TCurrencyService tCurrencyService;

    @Autowired
    private TAddressService tAddressService;
    //获取所有的类型
    @GetMapping("gettypelist")
    @ApiOperation("获取币种列表")
    public R gettypelist(){
        List<TCurrency>tCurrencyList=tCurrencyService.list(null);
        return R.ok(tCurrencyList);
    }


    @GetMapping("createBTC")
    @ApiOperation("钱包地址生成")
    public String createBTC(){
        NetworkParameters params = MainNetParams.get();//生成正式链地址用这个
        //生成地址
        ECKey key = new ECKey();
        System.out.println("地址："+key.toAddress(params).toString());
        System.out.println("公钥："+key.getPublicKeyAsHex());
        System.out.println("私钥（但是这个私钥导入不了IMtoken）："+key.getPrivateKeyAsHex());
        System.out.println("私钥（可以导进IMtoken）："+key.getPrivateKeyAsWiF(params));

        //根据上面不能导进IMtoken的私钥获得可以导进IMtoken的私钥：
        BigInteger priKey = new BigInteger("61c6f70faa8b046232be99b73f8a5cdf21917bdaf56b38dd7e37bc318dc10cf7",16);
        key = ECKey.fromPrivate(priKey);
        System.out.println("私钥："+key.getPrivateKeyAsWiF(params));
        System.out.println("地址："+key.toAddress(params));
        return  key.toAddress(params).toString();
    }


    /**
     * path路径
     */
    private final static ImmutableList<ChildNumber> BIP44_ETH_ACCOUNT_ZERO_PATH =
            ImmutableList.of(new ChildNumber(44, true), new ChildNumber(60, true),
                    ChildNumber.ZERO_HARDENED, ChildNumber.ZERO);

    @GetMapping("createWallet")
    @ApiOperation("创建钱包")
    private String createWallet()  throws MnemonicException.MnemonicLengthException {
        SecureRandom secureRandom = new SecureRandom();
        byte[] entropy = new byte[DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8];
        secureRandom.nextBytes(entropy);

        //生成12位助记词
        List<String> str = MnemonicCode.INSTANCE.toMnemonic(entropy);

        //使用助记词生成钱包种子
        byte[] seed = MnemonicCode.toSeed(str, "");
        DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
        DeterministicHierarchy deterministicHierarchy = new DeterministicHierarchy(masterPrivateKey);
        DeterministicKey deterministicKey = deterministicHierarchy
                .deriveChild(BIP44_ETH_ACCOUNT_ZERO_PATH, false, true, new ChildNumber(0));
        byte[] bytes = deterministicKey.getPrivKeyBytes();
        ECKeyPair keyPair = ECKeyPair.create(bytes);
        //通过公钥生成钱包地址
        String address = Keys.getAddress(keyPair.getPublicKey());

        System.out.println();
        System.out.println("助记词：");
        System.out.println(str);
        System.out.println();
        System.out.println("地址：");
        System.out.println("0x"+address);
        System.out.println();
        System.out.println("私钥：");
        System.out.println("0x"+keyPair.getPrivateKey().toString(16));
        System.out.println();
        System.out.println("公钥：");
        System.out.println(keyPair.getPublicKey().toString(16));
        return "0x"+address;
    }

    //添加钱包
    @PostMapping("addAddress")
    @ApiOperation("添加钱包地址")
    public R addAddress(@RequestBody TAddress tAddress) throws MnemonicException.MnemonicLengthException {
        SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        tAddress.setCreatetime(formatter.format(new Date()));
        if(tAddress.getCurrencyid()==1) {
            tAddress.setAddress(createBTC());
        }
        if(tAddress.getCurrencyid()==2) {
            tAddress.setAddress(createWallet());
        }
        try{
            tAddressService.save(tAddress);
            return R.ok("success");
        }
        catch (Exception ex){
            return R.failed(ex.toString());
        }
    }



    //编辑
    @GetMapping("deleteAddress")
    @ApiOperation("删除钱包地址")
    public R deleteAddress(@RequestParam("id")Integer id ){
        try{
            TAddress tAddress=tAddressService.getById(id);
            tAddressService.removeById(id);
            return R.ok("success");
        }
        catch (Exception ex){
            return R.failed(ex.toString());
        }
    }


}


